package service

import (
	"ruanGongKeShe16Zu/model"
	"ruanGongKeShe16Zu/repository"
	"ruanGongKeShe16Zu/service/vo"
	"sync"

	"github.com/gin-gonic/gin"
)

// 单例实现
var CartServiceInstance *CartService
var CartServiceOnce sync.Once

type CartService struct {
	Repository repository.CartRepository
}

func GetCartService() *CartService {
	CartServiceOnce.Do(func() {
		repository := repository.NewCartRepository().(repository.CartRepository)
		repository.DB.AutoMigrate(&model.Cart{})
		CartServiceInstance = &CartService{
			Repository: repository,
		}
	})
	return CartServiceInstance
}

func (s *CartService) Create(ctx *gin.Context, req *vo.CartReq) (*model.Cart, error) {
	instru, _ := repository.NewInstrumentRepository().SelectById(req.InstrumentID)
	// user, _ := ctx.Get("user")
	cartModel := model.Cart{
		UserID:          req.UserID,
		InstrumentID:    req.InstrumentID,
		InstrumentNum:   req.InstrumentNum,
		InstrumentName:  instru.Name,
		InstrumentDesc:  "XXX",
		InstrumentImg:   instru.Img,
		InstrumentUnit:  instru.Unit,
		InstrumentPrice: instru.Price,
	}
	cart, err := s.Repository.Create(&cartModel)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return nil, err
	}
	return cart, nil
}

func (s *CartService) Retrieve(ctx *gin.Context, id int) (*model.Cart, error) {
	cart, err := s.Repository.SelectById(id)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return nil, err
	}
	return cart, nil
}

func (s *CartService) Update(ctx *gin.Context, item *model.Cart, requestItem *vo.CartReq) (*model.Cart, error) {
	cart, err := s.Repository.Update(*item, *requestItem)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return nil, err
	}
	return cart, nil
}

func (s *CartService) Delete(ctx *gin.Context, id int) error {
	err := s.Repository.DeleteById(id)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return err
	}
	return nil
}

// CartList 列举分类
func (s *CartService) CartList(ctx *gin.Context, req *vo.ListCartReq) (resp *vo.DataListResp, err error) {
	carts, err := s.Repository.CartList()
	if err != nil {
		// utils.LogrusObj.Error(err)
		return
	}
	Resp := make([]*vo.ListCartResp, 0)
	for _, v := range carts {
		Resp = append(Resp, &vo.ListCartResp{
			ID:              v.ID,
			UserID:          v.UserID,
			InstrumentID:    v.InstrumentID,
			InstrumentNum:   v.InstrumentNum,
			InstrumentName:  v.InstrumentName,
			InstrumentDesc:  v.InstrumentDesc,
			InstrumentImg:   v.InstrumentImg,
			InstrumentUnit:  v.InstrumentUnit,
			InstrumentPrice: v.InstrumentPrice,
			CreatedAt:       v.CreatedAt.Local().Format("2006-01-02 15:04:05"),
		})
	}

	resp = &vo.DataListResp{
		Item:  Resp,
		Total: int64(len(Resp)),
	}

	return
}

func (s *CartService) SelectByUserID(ctx *gin.Context, req *vo.ListCartReq, id uint) (resp *vo.DataListResp, err error) {
	carts, err := s.Repository.SelectByUserID(req, id)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return
	}
	Resp := make([]*vo.ListCartResp, 0)
	for _, v := range carts {
		Resp = append(Resp, &vo.ListCartResp{
			ID:              v.ID,
			UserID:          v.UserID,
			InstrumentID:    v.InstrumentID,
			InstrumentNum:   v.InstrumentNum,
			InstrumentName:  v.InstrumentName,
			InstrumentDesc:  v.InstrumentDesc,
			InstrumentImg:   v.InstrumentImg,
			InstrumentUnit:  v.InstrumentUnit,
			InstrumentPrice: v.InstrumentPrice,
			CreatedAt:       v.CreatedAt.Local().Format("2006-01-02 15:04:05"),
		})
	}

	resp = &vo.DataListResp{
		Item:  Resp,
		Total: int64(len(Resp)),
	}

	return
}

func (s *CartService) DeleteByUserID(ctx *gin.Context, id uint) error {
	err := s.Repository.DeleteByUserID(id)
	if err != nil {
		// utils.LogrusObj.Error(err)
		return err
	}
	return nil
}
